package com.explment.lens.utils.jwt;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Date;

public class JwtUtils {

    private static final String SECRET_KEY = "6oHKDSQDtoeMTWFOISSN9-G5WtPbz0M6xJx8aSwoEk0";
    private static final long EXPIRATION_MS = 3600000; // 1小时

    /**
     * 生成JWT令牌
     *
     * @param userDetails 用户详细信息
     * @return JWT令牌字符串
     */
    public static String generateToken(UserDetails userDetails) {
        if (userDetails == null || userDetails.getUsername() == null) {
            throw new IllegalArgumentException("UserDetails cannot be null and must have a username");
        }
        if (SECRET_KEY == null || SECRET_KEY.getBytes().length < 32) {
            throw new IllegalArgumentException("Secret key must be at least 256 bits (32 bytes)");
        }
        if (EXPIRATION_MS <= 0) {
            throw new IllegalArgumentException("Expiration time must be positive");
        }
        return Jwts.builder()
                .setSubject(userDetails.getUsername())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_MS))
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

    /**
     * 从JWT令牌中提取用户名
     *
     * @param token JWT令牌字符串
     * @return 提取的用户名
     */
    public static String extractUsername(String token) {
        try {
            return Jwts.parser()
                    .setSigningKey(SECRET_KEY)
                    .parseClaimsJws(token)
                    .getBody()
                    .getSubject();
        } catch (JwtException e) {
            throw new JwtException("Failed to parse JWT token", e);
        }
    }

    /**
     * 验证JWT令牌的有效性
     *
     * @param token 需要验证的JWT令牌
     * @return 如果令牌有效则返回true，否则返回false
     * @throws Exception 如果在解析令牌时发生异常，会抛出异常
     */
    public static boolean validateToken(String token) {
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(SECRET_KEY)
                    .parseClaimsJws(token)
                    .getBody();

            // 检查过期时间
            Date expiration = claims.getExpiration();
            if (expiration.before(new Date())) {
                return false;
            }
            return true;
        } catch (Exception e) {
            // 捕获签名无效、令牌格式错误等异常
            return false;
        }
    }

}
